import os
import cv2
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.metrics import confusion_matrix, classification_report
from sklearn.svm import SVC
from sklearn.metrics import confusion_matrix
import matplotlib.pyplot as plt
import matplotlib as mpl
import pandas as pd
from sklearn.tree import DecisionTreeClassifier
from sklearn.neighbors import KNeighborsClassifier
from sklearn.naive_bayes import BernoulliNB

mpl.rcParams['font.sans-serif'] = ['KaiTi']
mpl.rcParams['font.serif'] = ['KaiTi']
# mpl.rcParams['axes.unicode_minus'] = False # 解决保存图像是负号'-'显示为方块的问题,或者转换负号为字符串

# ----------------------------------------------------------------------------------
# 第一步 切分训练集和测试集
# ----------------------------------------------------------------------------------

# X = []  # 定义图像名称
# Y = []  # 定义图像分类类标
# Z = []  # 定义图像像素'''

df = pd.read_excel('C:/Users/zlsjNKJS/Desktop/090/train.xlsx')
print(df)

def remove_extension(filename):
    return os.path.splitext(filename)[0]

df.iloc[:, 1] = df.iloc[:, 1].apply(remove_extension)

df.to_excel('C:/Users/zlsjNKJS/Desktop/090/modified_train.xlsx')

X_train_str = df.iloc[:, 1].tolist()
Y_train_str = df.iloc[:, 15].tolist()

X_train = [int(item) for item in X_train_str]
Y_train = [int(item) for item in Y_train_str]

print("X_train:", X_train)
print("Y_train:", Y_train)

df = pd.read_excel('C:/Users/zlsjNKJS/Desktop/090/val.xlsx')
print(df)

df.iloc[:, 1] = df.iloc[:, 1].apply(remove_extension)

df.to_excel('C:/Users/zlsjNKJS/Desktop/090/modified_val.xlsx')

X_val_str = df.iloc[:, 1].tolist()
Y_val = df.iloc[:, 15].tolist()

X_val = [int(item) for item in X_val_str]

print("X_val:", X_val)
print("Y_val:", Y_val)

print(len(X_train), len(X_val), len(Y_train), len(Y_val))

# ----------------------------------------------------------------------------------
# 第二步 图像读取及转换为像素直方图
# ----------------------------------------------------------------------------------

# 训练集
XX_train = []
for file_name in X_train_str:
    file_path = os.path.join('C:/Users/zlsjNKJS/Desktop/090/train', str(file_name)+'.jpg')
    image = cv2.imread(file_path, cv2.IMREAD_COLOR)

    if image is not None:
        # 图像像素大小一致
        img = cv2.resize(image, (256, 256),
                         interpolation=cv2.INTER_CUBIC)

        # 计算图像直方图并存储至X数组
        hist = cv2.calcHist([img], [0, 1], None,
                            [256, 256], [0.0, 255.0, 0.0, 255.0])

        XX_train.append(((hist / 255).flatten()))
    else:
        print(f"Image not found or cannot be read:{file_path}")

# 测试集
XX_val = []
for file_name in X_val_str:
    file_path = os.path.join('C:/Users/zlsjNKJS/Desktop/090/val', str(file_name) + '.jpg')
    image = cv2.imread(file_path, cv2.IMREAD_COLOR)

    if image is not None:
        # 图像像素大小一致
        img = cv2.resize(image, (256, 256),
                         interpolation=cv2.INTER_CUBIC)

        # 计算图像直方图并存储至X数组
        hist = cv2.calcHist([img], [0, 1], None,
                            [256, 256], [0.0, 255.0, 0.0, 255.0])

        XX_val.append(((hist / 255).flatten()))
    else:
        print(f"Image not found or cannot be read:{file_path}")

# ----------------------------------------------------------------------------------
# 第三步 基于支持向量机的图像分类处理
# ----------------------------------------------------------------------------------
# 常见核函数‘linear’, ‘poly’, ‘rbf’, ‘sigmoid’, ‘precomputed’
'''clf = SVC().fit(XX_train, Y_train)
clf = SVC(kernel="linear").fit(XX_train, Y_train)
predictions_labels = clf.predict(XX_val)'''

# ----------------------------------------------------------------------------------
# 第三步 基于决策树的图像分类处理
# ----------------------------------------------------------------------------------
'''clf = DecisionTreeClassifier().fit(XX_train, Y_train)
predictions_labels = clf.predict(XX_val)'''

# ----------------------------------------------------------------------------------
# 第三步 基于KNN的图像分类处理
# ----------------------------------------------------------------------------------
'''clf = KNeighborsClassifier(n_neighbors=11).fit(XX_train, Y_train)
predictions_labels = clf.predict(XX_val)'''

# ----------------------------------------------------------------------------------
# 第三步 基于朴素贝叶斯的图像分类处理
# ----------------------------------------------------------------------------------
clf = BernoulliNB().fit(XX_train, Y_train)
predictions_labels = clf.predict(XX_val)

print(u'预测结果:')
print(predictions_labels)
print(u'算法评价:')
print(classification_report(Y_val, predictions_labels))

# 输出前10张图片及预测结果
k = 0
while k < 58:
    file_path = os.path.join('C:/Users/zlsjNKJS/Desktop/090/val', X_val_str[k]+'.jpg')
    try:
        image = cv2.imread(file_path, cv2.IMREAD_COLOR)
        if image is not None:
#            cv2.imshow("img", image)
            print(X_val_str[k],Y_val[k],predictions_labels[k])

#            cv2.waitKey(0)
#            cv2.destroyAllWindows()
        else:
            print(f"Cannot read the image: {file_path}")
    except Exception as e:
        print(f"An error occurred while reading the image {file_path}:{e}")
    k = k+1


labels = [0, 1, 2, 3, 4]


y_true = Y_val  # 正确标签
y_pred = predictions_labels  # 预测标签

tick_marks = np.array(range(len(labels))) + 0.5


def plot_confusion_matrix(cm, title='Confusion Matrix', cmap=plt.cm.Blues):
    plt.imshow(cm, interpolation='nearest', cmap=cmap)
    plt.title(title)
    plt.colorbar()
    xlocations = np.array(range(len(labels)))
    plt.xticks(xlocations, labels, rotation=90)
    plt.yticks(xlocations, labels)
    plt.ylabel('True label')
    plt.xlabel('Predicted label')
    for i, row in enumerate(cm):
        for j, value in enumerate(row):
            plt.text(j, i, f"{value}", ha="center", va="center", color="black", fontsize=12)


cm = confusion_matrix(y_true, y_pred)
'''np.set_printoptions(precision=2)
cm_normalized = cm.astype('float') / cm.sum(axis=1)[:, np.newaxis]
print(cm_normalized)'''
print(cm)
plt.figure(figsize=(12, 8), dpi=120)

'''ind_array = np.arange(len(labels))
x, y = np.meshgrid(ind_array, ind_array)

for x_val, y_val in zip(x.flatten(), y.flatten()):
    c = cm_normalized[y_val][x_val]
    if c > 0.01:
        plt.text(x_val, y_val, "%0.2f" % (c,), color='red', fontsize=7, va='center', ha='center')
# offset the tick
plt.gca().set_xticks(tick_marks, minor=True)
plt.gca().set_yticks(tick_marks, minor=True)
plt.gca().xaxis.set_ticks_position('none')
plt.gca().yaxis.set_ticks_position('none')
plt.grid(True, which='minor', linestyle='-')
plt.gcf().subplots_adjust(bottom=0.15)'''

plot_confusion_matrix(cm, title=' Bayes Confusion Matrix')
# show confusion matrix
plt.savefig('confusion_matrix_conuts.png', format='png')
plt.show()